package gl.java.umsp.room;

import gl.java.game.GameEngine;
import gl.java.game.NetEvent;
import gl.java.game.NetEventReceiver;
import gl.java.umsp.Umsp;
import gl.java.umsp.UmspHeader;
import gl.java.umsp.bean.Room;
import gl.java.umsp.bean.User;
import gl.java.umsp.router.ChannelRouter;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@ChannelHandler.Sharable
public class RoomMessageDispatcher extends SimpleChannelInboundHandler<UmspHeader> {
    public RoomMessageDispatcher() {
        GameEngine.getInstance().setNetWorkEventReceiver(new NetEventReceiver() {
            @Override
            public void onReceiver(NetEvent netEvent) {
                {
                    UmspHeader msg = (UmspHeader) netEvent.frame;
                    ChannelHandlerContext ctx = (ChannelHandlerContext) netEvent.context;
                    RoomPool pool = RoomPool.getInstance();
                    switch (msg.cmd) {
                        case Umsp.CMD_ROOM_ENTER:
                            String roomSession = new String(msg.payload);
                            User user = User.creatUser(msg);
                            ChannelRouter.getInstance().registerRouter(user.userID, ctx.channel());
                            log.info("user '" + user.userID + "' want enter room, roomSession:" + roomSession);
                            Room room = pool.findRoomAndCreateIfNotExist(roomSession);
                            room.getRoomUserList().put(user.userID, user);
                            RoomService.INSTANCE.onUserEnter(room, user);
                            break;
                        case Umsp.CMD_ROOM_EXIT:
                            Room roomFrom = pool.findRoomByUserID(msg.userID);
                            User removeUser = roomFrom.getRoomUserList().remove(msg.userID);
                            ChannelRouter.getInstance().unRegisterRouter(ctx.channel());
                            RoomService.INSTANCE.onUserExit(roomFrom, removeUser);
                            ctx.close();
                            break;
                        case Umsp.CMD_MSG:
                            RoomService.INSTANCE.onUserSendMsg(msg, pool.findRoomByUserID(msg.userID));
                            break;
                        case Umsp.CMD_ROOM_SERVICE_LOGIN_RSP:
                            break;
                        case Umsp.CMD_HEARTBEAT:
                            Umsp.returnHeart(ctx.channel());
                            break;
                        default:
                            log.warn("receive a unknown msg :" + msg);
                            break;
                    }
                }
            }

        });
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, UmspHeader msg) {
        GameEngine.getInstance().addNetWorkEvent(new NetEvent(ctx, msg));
    }
}